﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net.Sockets;
using System.Net;
using System.Threading;
using _2QWebProxy.App_Code;

namespace _2QWebProxy
{
    public class ProxyClient
    {
        public Thread ReceiveThread;
        public Socket client;
        public CClient browserClient;


        public ProxyClient(string ip, int port, CClient browserClient)
        {
            client = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            this.browserClient = browserClient;
            do
            {
                try
                {
                    client.Connect(new IPEndPoint(IPAddress.Parse(ip), port));
                }
                catch (Exception ex) { }
            } while (!client.Connected);
            this.ReceiveThread = new Thread(new ThreadStart(RedirectPackets));
            this.ReceiveThread.Start();

        }

        private void RedirectPackets()
        {

            try
            {
                byte[] buffer;
                string temp = "";
                while (client.Connected)
                {
                    buffer = new byte[65535];
                    int recv = client.Receive(buffer);
                    Array.Resize(ref buffer, recv);
                    // Apply rule
                    bool rule = true;
                    if (recv == 0)
                    {
                        this.ReceiveThread.Abort();
                        return;
                    }
                    if (Properties.Settings.Default.isRule)
                    {
                        string contentType = "";
                        temp = Utils.FilterHeader(Encoding.GetEncoding("UTF-8").GetString(buffer), "Content-Type");

                        if (temp != "") contentType = temp;
                        rule = Utils.CheckRules(GlobalVariables.host, GlobalVariables.ipAddress, contentType);
                        if (!rule)
                        {
                            string str = BuildRequestHeader(buffer);
                            buffer = Encoding.ASCII.GetBytes(str);
                            browserClient.SendToBrowser(buffer);
                        }
                        //}
                    }

                    //Send request to browser
                    if (rule)
                    {
                        browserClient.SendToBrowser(buffer);
                    }
                }
            }
            catch (Exception ex)
            {

            }

        }

        public string BuildRequestHeader(byte[] buffer)
        {
            string response = "\r\n\r\n";
            string str = Encoding.GetEncoding("UTF-8").GetString(buffer);
            string subString = str.Substring(str.IndexOf("Content-Length"));
            string contentLength = subString.Substring(0, subString.IndexOf("\r\n"));
            str = str.Replace(contentLength, String.Format("Content-Length: {0}", Encoding.Unicode.GetBytes(response).Length));
            string content = subString.Substring(subString.IndexOf("\r\n\r\n") + 8);
            str = str.Replace(content, response);
            return str;
        }

        public string GetHeader(Socket socket, out byte[] arrByte)
        {
            string header = "";
            int i = 0;
            arrByte = new byte[65535];
            while (true)
            {
                byte[] bytes = new byte[1];
                int bytesRec = socket.Receive(bytes);
                header += System.Text.Encoding.ASCII.GetString(bytes, 0, bytesRec);
                arrByte[i] = bytes[0];
                i++;
                if (header.IndexOf("\r\n\r\n") > -1 || header.IndexOf("\n\n") > -1)
                {
                    break;
                }
            }
            Array.Resize(ref arrByte, i);
            return header;
        }

        public void SendToServer(byte[] packet)
        {
            client.Send(packet);
        }
    }
}
